# -*- coding: utf-8 -*-
# FileName:     x86_gui.py
# time:         23/1/2 002 下午 7:38
# Author:       Zhou Hang
# Description:  I don't want to write
import sys
from pathlib import Path

from PyQt5.QtGui import QTextCursor, QIcon
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QMessageBox, QTabWidget

from common.zerror import MyCoreError
from x86ThreadSim.src.core.x86 import Core
from x86ThreadSim.src.gui.custom_module import RoundMainWindow
from x86ThreadSim.src.ui.x86_ui import Ui_x86


class x86_gui(QMainWindow, Ui_x86):
#class x86_gui(RoundMainWindow, Ui_x86):
    def __init__(self):
        super(x86_gui, self).__init__()
        self.core = None
        self.has_choose_code = False
        self.reg_names = ['ax', 'bx', 'cx', 'dx', 'sp', 'bp']

        self.setupUi(self)
        self.setWindowIcon(QIcon('../resources/main_icon.png'))
        self.init_argv_table()

        self.threads_sb.valueChanged.connect(self.change_argv_table)
        self.choose_code_btn.clicked.connect(self.choose_code)
        self.start_btn.clicked.connect(self.start_simulation)
        self.ret2default_btn.clicked.connect(self.ret2default)
        self.save_btn.clicked.connect(self.save_code)

    def init_argv_table(self):
        threads = int(self.threads_sb.text())
        self.argv_table.setCR(threads, 6, [f'线程{i}' for i in range(threads)], self.reg_names)

    def change_argv_table(self):
        threads = int(self.threads_sb.text())
        self.argv_table.setCR(threads, 6, [f'线程{i}' for i in range(threads)], self.reg_names)

    def choose_code(self):
        code_file, file_type = QFileDialog.getOpenFileName(self, '打开文件', '../input', '*.s')
        if code_file == '':
            return
        self.code_edit.clear()
        self.has_choose_code = True
        self.code_lbl.setText(code_file)
        code_ = Path(code_file).read_text()
        self.code_edit.setText(code_)

    def save_code(self):
        code = self.code_edit.toPlainText()
        code_file = Path(self.code_lbl.text())
        code_file.write_text(code, encoding='utf-8')

    def start_simulation(self):
        if not self.has_choose_code:
            QMessageBox.warning(self, '警告', '请选择代码文件')
            return

        # args = {
        #     "seed": self.seed_sb.value(),
        #     "threads": self.threads_sb.value(),
        # }

        seed = self.seed_sb.value()
        threads = self.threads_sb.value()
        self.save_code()
        program = self.code_lbl.text()
        interrupt = self.interrupt_sb.value()
        randints = self.randints_cb.isChecked()
        argv = self.argv_table.get_argv()
        loadaddr = self.loadaddr_sb.value()
        memsize = self.memsize_sb.value()
        memtrace = self.memtrace_edit.text()
        regtrace = []
        if self.ax_cb.isChecked():
            regtrace.append('ax')
        if self.bx_cb.isChecked():
            regtrace.append('bx')
        if self.cx_cb.isChecked():
            regtrace.append('cx')
        if self.dx_cb.isChecked():
            regtrace.append('dx')
        if self.sp_cb.isChecked():
            regtrace.append('sp')
        if self.bp_cb.isChecked():
            regtrace.append('bp')
        regtrace = ','.join(regtrace)
        cctrace = self.cctrace_cb.isChecked()
        printstats = self.printstats_cb.isChecked()

        save_stdout = sys.stdout
        sys.stdout = open("../output/test.txt", "w", encoding='utf-8')
        try:
            self.core = Core(seed, threads, program, interrupt, randints, argv, loadaddr, memsize,
                             memtrace, regtrace, cctrace, printstats)
            sys.stdout.close()

            sys.stdout = open("../output/argv.txt", "w", encoding='utf-8')
            self.core.show_args()
        except MyCoreError as e:
            QMessageBox.warning(self, '警告', str(e))
            return
        finally:
            sys.stdout.close()
            sys.stdout = save_stdout

        result = Path("../output/test.txt")
        self.result_edit.setText(result.read_text(encoding='utf-8'))
        self.result_edit.moveCursor(QTextCursor.Start)

        argv_ = Path("../output/argv.txt")
        self.param_edit.setText(argv_.read_text(encoding='utf-8'))
        self.param_edit.moveCursor(QTextCursor.Start)
        self.param_edit.set_line_height(15)

        self.main_tab_wgt.setCurrentWidget(self.result_tab)

    def ret2default(self):
        self.seed_sb.setValue(0)
        self.threads_sb.setValue(2)
        self.interrupt_sb.setValue(4)
        self.randints_cb.setChecked(False)
        self.argv_table.update()
        self.loadaddr_sb.setValue(1000)
        self.memsize_sb.setValue(128)
        self.memtrace_edit.setText('2000')
        self.ax_cb.setChecked(False)
        self.bx_cb.setChecked(False)
        self.cx_cb.setChecked(False)
        self.dx_cb.setChecked(False)
        self.sp_cb.setChecked(False)
        self.bp_cb.setChecked(False)
        self.cctrace_cb.setChecked(False)
        self.printstats_cb.setChecked(False)


def main():
    pass


if __name__ == "__main__":
    main()
